/*
 * @Description 
 * @Autor lzhiqiang
 * @Date 2023-03-21 16:40:12
 * @LastEditors lzhiqiang
 * @LastEditTime 2023-04-05 14:42:57
 */
#include "http_session.h"

#include "log.h"

namespace johnsonli 
{
namespace http 
{
    static johnsonli::Logger::ptr g_logger = LOG_NAME("system");

    HttpSession::HttpSession(Socket::ptr sock, bool owner)
        :SocketStream(sock, owner) 
    {}

    HttpRequest::ptr HttpSession::recvRequest() 
    {
        HttpRequestParser::ptr parser(new HttpRequestParser);
        uint64_t buff_size = HttpRequestParser::GetHttpRequestBufferSize();
        //uint64_t buff_size = 150;
        std::shared_ptr<char> buffer(
        new char[buff_size], [](char* ptr){
            delete[] ptr;
        });

        char* data = buffer.get();
        int offset = 0;
        do
        {
            //LOG_INFO(g_logger) << "read";
            int len = read(data + offset, buff_size - offset);
            if(len <= 0)    //出错
            {
 //               LOG_DEBUG(g_logger) << "len <= 0";
                close();
                return nullptr;
            }

            len += offset;

            size_t nparse = parser->execute(data, len);
            if(parser->hasError()) {
                LOG_INFO(g_logger) << "parser->hasError()";
                close();
                return nullptr;
            }

            offset = len - nparse;

            if(offset == (int)buff_size) 
            {
                LOG_INFO(g_logger) << "offset == (int)buff_size";
                close();
                return nullptr;
            }
            if(parser->isFinished())    //请求头解析完成
            {
                break;
            }

        }while(true);
       
       int64_t length = parser->getContentLength();
       if(length > 0) 
       {
            std::string body;
            body.resize(length);

            int len = 0;
            if(length >= offset) 
            {
                memcpy(&body[0], data, offset);
                len = offset;
            } 
            else 
            {
                memcpy(&body[0], data, length);
                len = length;
            }
            length -= offset;
            if(length > 0) 
            {
                if(readFixSize(&body[len], length) <= 0) 
                {
                    close();
                    return nullptr;
                }
            }
            parser->getData()->setBody(body);
        }

        //LOG_INFO(g_logger) << "recv end";

        
// LOG_INFO(g_logger) << "connection: "  << parser->getData()->getHeader("connection");
        parser->getData()->init();
        
        
        return parser->getData();
        
        
    }

    int HttpSession::sendResponse(HttpResponse::ptr rsp) {
        std::stringstream ss;
        ss << *rsp;
        std::string data = ss.str();
        return writeFixSize(data.c_str(), data.size());
    }
}
}